Conversation
* command-cert-manager-issuer 2.6.0: Optional CA, Updated Default Healthcheck Interval, Updated Service Account Token Lifecycle (#70) * feat: Add volume and volume mount for service token * chore: fix sources and add changelog Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com> * feat(enrollment): make certificateAuthorityLogicalName be optional when using enrollment patterns Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com> * updated error messaging on csr enrollment Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com> * Update generated docs * chore: update docs + add e2e test for optional CA Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com> * Update generated docs * feat(healthcheck): bump default healthcheck interval from 1m to 10m Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com> * chore(deps): bump go version to 1.26 Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com> * Update generated docs * chore: address copilot feedback. update linter version Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com> * Update generated docs * chore(ci): bump controller tools version Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com> * chore(docs): document new Helm chart values for serviceAccount Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com> --------- Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com> Co-authored-by: Sven Rajala <sven.rajala@keyfactor.com> Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * command-cert-manger-issuer v2.6.1: Add priorityClassName to Deployment (#74) * command-cert-manager-issuer 2.6.0: Optional CA, Updated Default Healthcheck Interval, Updated Service Account Token Lifecycle (#70) (#71) * feat: Add volume and volume mount for service token * chore: fix sources and add changelog * feat(enrollment): make certificateAuthorityLogicalName be optional when using enrollment patterns * updated error messaging on csr enrollment * Update generated docs * chore: update docs + add e2e test for optional CA * Update generated docs * feat(healthcheck): bump default healthcheck interval from 1m to 10m * chore(deps): bump go version to 1.26 * Update generated docs * chore: address copilot feedback. update linter version * Update generated docs * chore(ci): bump controller tools version * chore(docs): document new Helm chart values for serviceAccount --------- Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com> Co-authored-by: Matthew H. Irby <irby@users.noreply.github.com> Co-authored-by: Sven Rajala <sven.rajala@keyfactor.com> Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * Add priorityClassName * remove quote * Update README * chore(AB#89226): add docs on how to contribute to the project Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com> * chore: update CHANGELOG Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com> Co-authored-by: Morgan Gangwere <470584+indrora@users.noreply.github.com> Co-authored-by: Sven Rajala <sven.rajala@keyfactor.com> Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> Co-authored-by: slammajamma28 <slammajamma28@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com> Co-authored-by: Matthew H. Irby <irby@users.noreply.github.com> Co-authored-by: Sven Rajala <sven.rajala@keyfactor.com> Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> Co-authored-by: slammajamma28 <slammajamma28@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com>
There was a problem hiding this comment.
🟡 Changes recommended
The new ambient-token expiration handling currently logs at Info level without preventing use of an already-expired token, which can create noisy logs and lead to immediate runtime failures.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR adds diagnostic logging around ambient (cloud-provided) access token expiration when generating the Command OAuth configuration, and extends the Helm chart to optionally set a pod priorityClassName, alongside documentation/changelog updates.
Changes:
- Log the
expclaim (when present) from ambient access tokens during server config creation. - Add
priorityClassNameto the Helm chart values and render it into the Deployment pod spec when set. - Update chart documentation, contributing guide structure, and bump the changelog to v2.6.1.
File summaries
| File | Description |
|---|---|
| internal/command/command.go | Adds parsing/logging of ambient token expiration during OAuth server config generation. |
| deploy/charts/command-cert-manager-issuer/values.yaml | Introduces priorityClassName chart value (default empty). |
| deploy/charts/command-cert-manager-issuer/templates/deployment.yaml | Conditionally sets priorityClassName on the PodSpec. |
| deploy/charts/command-cert-manager-issuer/README.md | Updates the configuration table to reflect current chart values (including priorityClassName). |
| CONTRIBUTING.md | Restructures contribution/development guidance and updates requirements to match go.mod. |
| CHANGELOG.md | Adds v2.6.1 notes for the chart/docs updates. |
Review details
- Files reviewed: 6/6 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…ntial generation Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com>
There was a problem hiding this comment.
🟡 Changes recommended
The new token source implementation has a confirmed Azure error-wrapping inconsistency and context-capture/documentation issues that can impact reliability when cached clients outlive the originating reconcile context.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (3)
internal/command/client.go:168
- This comment references newAzureDefaultCredentialSource, but that function no longer exists after the refactor, so it's misleading/outdated.
// Fail fast if the credentials/scopes are wrong, same as
// newAzureDefaultCredentialSource does today.
if _, err := src.Token(); err != nil {
internal/command/client.go:243
- This comment uses second-person phrasing ("your") and references newAzureDefaultCredentialSource, which doesn't exist anymore; please reword to be accurate and impersonal.
// Fail fast if the credentials/scopes are wrong, same as your
// newAzureDefaultCredentialSource does today.
if _, err := src.Token(); err != nil {
internal/command/client.go:239
- Same caching issue as Azure: this source is stored inside a cached client, so capturing a cancelable reconcile ctx can make future token refreshes fail. Strip cancellation before storing ctx.
src := &gcpTokenSource{
ctx: ctx,
audience: audience,
scopes: scopes,
}
- Files reviewed: 8/9 changed files
- Comments generated: 4
- Review effort level: Lite
| func (a *azureTokenSource) Token() (*oauth2.Token, error) { | ||
| // Try Azure with a short timeout | ||
| timeoutCtx, cancel := context.WithTimeout(ctx, 10*time.Second) | ||
| timeoutCtx, cancel := context.WithTimeout(a.ctx, 10*time.Second) | ||
| defer cancel() | ||
|
|
Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com>
There was a problem hiding this comment.
🟡 Changes recommended
The new token-source implementation introduces security/performance concerns (JWT claims logged at Info level; GCP TokenSource mutex serializes requests) and lacks accompanying tests for the new rotation/refresh behavior.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (6)
Previously missed (3) — in code that hasn't changed since the last review.
internal/command/client.go:124
- This stores the full Azure access token string in-memory in
a.lastjust to detect rotation, which unnecessarily retains a secret. Prefer tracking a non-secret value (e.g., the expiry timestamp) for rotation detection.
This issue also appears on line 215 of the same file.
internal/command/client.go:132
- JWT claim logging is emitted at Info level, which can leak identity details (e.g., oid/email/appid) into normal logs. Consider moving this block to a verbose logger (e.g., V(1)+) so it’s only shown when explicitly enabled.
This issue also appears on line 224 of the same file.
CHANGELOG.md:4
- The PR description focuses on ambient credential expiration/refresh, but the v2.6.1 changelog entry doesn’t mention that behavior change. Adding a brief feature bullet will help users understand why this release is needed.
internal/command/client.go:227
- JWT claim logging is emitted at Info level, which can leak identity details (e.g., email/sub) into normal logs. Consider moving this block to a verbose logger (e.g., V(1)+) so it’s only shown when explicitly enabled.
log.Info("==== BEGIN DEBUG: Default Google ID Token JWT ======")
printClaims(log, token.AccessToken, []string{"aud", "iss", "sub", "email"})
log.Info("==== END DEBUG: Default Google ID Token JWT ======")
g.claimsShown = true
internal/command/client.go:218
- This stores the full GCP ID token string in-memory in
g.lastjust to detect rotation, which unnecessarily retains a secret. Prefer tracking a non-secret value (e.g., the expiry timestamp) for rotation detection.
if token.AccessToken != g.last {
log.Info(fmt.Sprintf("Access token issued from GCP. Token expires at UTC time %s", token.Expiry.UTC().Format(time.RFC3339)))
g.last = token.AccessToken
}
internal/command/client.go:146
- New ambient token source behavior (refreshable oauth2.TokenSource, rotation/claims logging) is not covered by unit tests, even though
internal/commandalready has tests. Consider adding tests using a fakeazcore.TokenCredentialand a fakeoauth2.TokenSourceto verify rotation detection and one-time claim logging without requiring real cloud credentials.
func newAzureTokenSource(ctx context.Context, scopes []string) (oauth2.TokenSource, error) {
log := log.FromContext(ctx)
log.Info("creating new Azure Default Token Source")
- Files reviewed: 8/9 changed files
- Comments generated: 1
- Review effort level: Lite
Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com>
There was a problem hiding this comment.
🔵 Needs a closer look
Add ambient token refresh/fallback coverage, bound GCP ID-token refresh calls, and document the ambient-auth change in the release notes.
Review details
Suppressed comments (4)
Previously missed (2) — in code that hasn't changed since the last review.
internal/command/client.go:238
- Because
g.ctxwas created withcontext.WithoutCancel, the ID-token source used here has no cancellation or deadline for futureinner.Token()calls. The 10-second timeout above only coversFindDefaultCredentials; a hung GCP metadata/IAM exchange can therefore block signer initialization and later refreshes indefinitely while holdingg.mu, stalling requests. Please use a bounded HTTP/context strategy for the ID-token refreshes as well.
CHANGELOG.md:3 - The v2.6.1 notes document the chart and contributor-guide changes, but omit the user-visible ambient-auth change implemented here: Azure/GCP credentials are now supplied through a refreshing external token source instead of a one-time access token. Please add that feature to the release notes so they match the shipped authentication behavior.
internal/command/client.go:103
- The new ambient path is not covered by the existing tests:
TestNewServerConfigonly exercises basic/OAuth configurations, and there are no tests for either token source's refresh/rotation or Azure-to-GCP fallback. Add deterministic credential/token-source tests (including an expired token followed by a rotated token) so the expiration behavior introduced here is protected from regressions.
func (a *azureTokenSource) Token() (*oauth2.Token, error) {
internal/command/command.go:226
- This PR's main behavior change is the long-lived rotating ambient
oauth2.TokenSource, but the command tests only cover direct-auth configuration and claim parsing; there is no coverage for Azure/GCPToken()returningExpiryor propagating a rotated token through the external-token configuration. Add fake credential/token-source tests for the refresh and expiry paths before relying on this authentication flow.
WithExternalTokenSource(source).
- Files reviewed: 8/9 changed files
- Comments generated: 0 new
- Review effort level: Lite
Signed-off-by: Matthew H. Irby <matt.irby@keyfactor.com>
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved moderate issues remain around token timeouts, repeated provider probes, and missing rotation tests.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (1)
internal/command/command.go:212
- On a GCP-only deployment, this creates a fresh Azure source and performs its failed
Token()probe for every distinct ambient configuration; the probe can consume the 10-second timeout inazureTokenSource.Token.ClientCacheholds its write lock whilenewInternalSignerruns, so multiple issuers serialize these probes and can delay creation of every subsequent client. Cache provider availability/credential construction separately (while keeping scopes/audience per client), or otherwise avoid re-probing Azure for each cached client.
source, err := newAzureTokenSource(ctx, config.AmbientCredentialScopes)
- Files reviewed: 4/5 changed files
- Comments generated: 2
- Review effort level: Lite
v2.6.2
Fixes